package lacus.wd_cinema.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 日志记录设置，
 * 记录service层与controller层的所有方法
 * @author lacus
 * @version 0.1
 * @since 0.1
 */
@Aspect
@Component
@Slf4j
public class LoggingConfig {

    @Pointcut("execution(* lacus.wd_cinema.controller..*(..))")
    public void logController() {
    }

    @Pointcut("execution(* lacus.wd_cinema.service..*(..))")
    public void logService() {
    }

    @Pointcut("execution(* lacus.wd_cinema.handler..*(..))")
    public void logHandler() {
    }

    @Around("logController() || logService() || logHandler()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        Object[] args = joinPoint.getArgs();
        // 记录调用时传参
        log.info("=> {}.{}() 传参: {}",
                className, methodName, args);
        Object result;
        try {
            result = joinPoint.proceed();
        } catch (Exception e) {
            // 记录发生的异常
            log.error(
                    "<= {}.{}() 异常：{}",
                    className, methodName,
                    e.getClass().getName(), e);
            throw e;
        }
        // 记录返回值
        log.info("<= {}.{}() 返回: {}",
                className, methodName, result);

        return result;
    }
}
